package org.sxp.common.utils;

import cn.hutool.core.util.StrUtil;
import cn.hutool.db.Db;
import cn.hutool.db.Entity;
import cn.hutool.db.Page;
import cn.hutool.db.dialect.DriverUtil;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.mongodb.*;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.MongoIterable;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.bson.Document;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.jdbc.support.JdbcUtils;
import org.sxp.common.dto.DatabaseDTO;
import org.sxp.common.dto.TableNamesDTO;
import org.sxp.common.enums.DbTypeEnum;
import org.sxp.common.exception.DataAccessException;
import org.sxp.common.validator.ValidatorUtils;
import org.sxp.common.validator.group.MysqlGroup;
import org.sxp.common.validator.group.OracleGroup;

import javax.sql.DataSource;
import java.sql.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * @author shenxingping
 * @date 2021/12/30
 */
public class DbUtil {

    public static final String MONGODB_URL_STARTWITH = "mongodb:";
    /**
     * url 模板
     */
    private static Map<String, String> DB_URL_TEMPLATE = new ConcurrentHashMap();
    /**
     * 查询所有表
     * @param database
     * @return
     */
    private static Map<String, String> DB_TABLE_NAME = new ConcurrentHashMap();
    /**
     * 查询所有表字段
     * @param database
     * @return
     */
    private static Map<String, String> DB_TABLE_FIELD_NAME = new ConcurrentHashMap();

    static {
        DB_URL_TEMPLATE.put(DbTypeEnum.mysql.name(), "jdbc:mysql://{host}:{port}/{database}?useUnicode=true&characterEncoding=UTF-8&useSSL=false");
        DB_URL_TEMPLATE.put(DbTypeEnum.oracleServerName.name(), "jdbc:oracle:thin:@//{host}:{port}/{service_name}");
        DB_URL_TEMPLATE.put(DbTypeEnum.oracleSid.name(), "jdbc:oracle:thin:@{host}:{port}:{sid}");
        DB_URL_TEMPLATE.put(DbTypeEnum.sqlServer.name(), "jdbc:sqlserver://{host}:{port};DatabaseName={database}");
        DB_URL_TEMPLATE.put(DbTypeEnum.dm.name(), "jdbc:dm://{host}:{port}/{database}");
        DB_URL_TEMPLATE.put(DbTypeEnum.postgresql.name(), "jdbc:postgresql://{host}:{port}/{database}");
        DB_URL_TEMPLATE.put(DbTypeEnum.hive.name(), "jdbc:hive2://{host}:{port}/{database}");
        /**
         * jdbc:mysql方便admin不用导入oceanBase驱动包
         * dataX执行ServerConnectInfo时会将jdbc:mysql:替换为jdbc:oceanbase:
         */
        DB_URL_TEMPLATE.put(DbTypeEnum.oceanbase.name(), "jdbc:mysql://{host}:{port}/{database}?useUnicode=true&characterEncoding=UTF-8&useSSL=false");

        DB_TABLE_NAME.put(DbTypeEnum.mysql.name(), "SELECT table_name tableName,table_comment tableComment,create_time createTime FROM information_schema.tables WHERE table_schema = (SELECT DATABASE())");
        DB_TABLE_NAME.put(DbTypeEnum.oracle.name(), "SELECT dt.table_name AS tableName, dtc.comments AS tableComment FROM user_tables dt,user_tab_comments dtc where dt.table_name=dtc.table_name UNION ALL SELECT uv.view_name AS tableName,uvc.COMMENTs AS tableComment FROM user_views uv LEFT JOIN user_tab_comments uvc ON uv.view_name = uvc.table_name");
        DB_TABLE_NAME.put(DbTypeEnum.sqlServer.name(), "select * from (select cast(so.name as varchar(500)) as tableName, cast(sep.value as varchar(500)) as tableComment, getDate() as createTime from sysobjects so left JOIN sys.extended_properties sep on sep.major_id=so.id and sep.minor_id=0 where (xtype='U' or xtype='v')) t order by t.tableName");
        DB_TABLE_NAME.put(DbTypeEnum.dm.name(), "SELECT dt.table_name AS tableName, dtc.comments AS tableComment FROM user_tables dt,user_tab_comments dtc where dt.table_name=dtc.table_name");
        DB_TABLE_NAME.put(DbTypeEnum.postgresql.name(), "select tablename as \"tableName\" from pg_tables");
        DB_TABLE_NAME.put(DbTypeEnum.oceanbase.name(), "SELECT table_name tableName,table_comment tableComment,create_time createTime FROM information_schema.tables WHERE table_schema = (SELECT DATABASE())");
        DB_TABLE_NAME.put(DbTypeEnum.hive.name(), "show tables");

        DB_TABLE_FIELD_NAME.put(DbTypeEnum.mysql.name(), "SELECT column_name columnName, data_type dataType,column_comment columnComment, column_key columnKey FROM information_schema.columns WHERE table_name = '{tableName}' AND table_schema = (SELECT DATABASE()) ORDER BY ordinal_position");
        DB_TABLE_FIELD_NAME.put(DbTypeEnum.oracle.name(), "select temp.column_name \"columnName\",temp.data_type \"dataType\",temp.comments \"columnComment\",case temp.constraint_type when 'P' then 'PRI' when 'C' then 'UNI' else '' end \"columnKey\" from (select col.column_id,col.column_name,col.data_type, colc.comments,uc.constraint_type,row_number() over (partition by col.column_name order by uc.constraint_type desc) as row_flg from user_tab_columns col left join user_col_comments colc on colc.table_name = col.table_name and colc.column_name = col.column_name left join user_cons_columns ucc on ucc.table_name = col.table_name and ucc.column_name = col.column_name left join user_constraints uc on uc.constraint_name = ucc.constraint_name where col.table_name = upper('{tableName}')) temp where temp.row_flg = 1 order by temp.column_id");
        DB_TABLE_FIELD_NAME.put(DbTypeEnum.sqlServer.name(), "SELECT cast(b.NAME AS VARCHAR(500)) AS columnName,cast(sys.types.NAME AS VARCHAR(500)) AS dataType,cast(c.VALUE AS VARCHAR(500)) AS columnComment,(SELECT CASE count( 1 ) WHEN 1 then 'PRI' ELSE '' END FROM syscolumns,sysobjects,sysindexes,sysindexkeys,systypes WHERE syscolumns.xusertype = systypes.xusertype AND syscolumns.id = object_id(A.NAME) AND sysobjects.xtype = 'PK' AND sysobjects.parent_obj = syscolumns.id AND sysindexes.id = syscolumns.id AND sysobjects.NAME = sysindexes.NAME AND sysindexkeys.id = syscolumns.id AND sysindexkeys.indid = sysindexes.indid AND syscolumns.colid = sysindexkeys.colid AND syscolumns.NAME = B.NAME\n" + "\t\t\t) as columnKey,'' as extra\n" + "\t\tFROM ( select name,object_id from sys.tables UNION all select name,object_id from sys.views) a INNER JOIN sys.COLUMNS b ON b.object_id = a.object_id LEFT JOIN sys.types ON b.user_type_id = sys.types.user_type_id LEFT JOIN sys.extended_properties c ON c.major_id = b.object_id AND c.minor_id = b.column_id WHERE a.NAME = '{tableName}' and sys.types.NAME != 'sysname'");
        DB_TABLE_FIELD_NAME.put(DbTypeEnum.dm.name(), "select temp.column_name \"columnName\",temp.data_type \"dataType\",temp.comments \"columnComment\",case temp.constraint_type when 'P' then 'PRI' when 'C' then 'UNI' else '' end \"columnKey\" from (select col.column_id,col.column_name,col.data_type, colc.comments,uc.constraint_type,row_number() over (partition by col.column_name order by uc.constraint_type desc) as row_flg from user_tab_columns col left join user_col_comments colc on colc.table_name = col.table_name and colc.column_name = col.column_name left join user_cons_columns ucc on ucc.table_name = col.table_name and ucc.column_name = col.column_name left join user_constraints uc on uc.constraint_name = ucc.constraint_name where col.table_name = upper('{tableName}')) temp where temp.row_flg = 1 order by temp.column_id");
        DB_TABLE_FIELD_NAME.put(DbTypeEnum.postgresql.name(), "select column_name as \"columnName\", data_type as \"dataType\" from information_schema.columns where table_name='{tableName}'");
        DB_TABLE_FIELD_NAME.put(DbTypeEnum.oceanbase.name(), "SELECT column_name columnName, data_type dataType,column_comment columnComment, column_key columnKey FROM information_schema.columns WHERE table_name = '{tableName}' AND table_schema = (SELECT DATABASE()) ORDER BY ordinal_position");
        DB_TABLE_FIELD_NAME.put(DbTypeEnum.hive.name(), "describe {tableName}");
    }

    public static String convertJdbcUrl(DatabaseDTO database){

        if(database.getType().equals(DbTypeEnum.mysql.getCode())){
            ValidatorUtils.validateEntity(database, MysqlGroup.class);
            return DB_URL_TEMPLATE.get(DbTypeEnum.mysql.name())
                    .replace("{host}", database.getHost())
                    .replace("{port}", database.getPort())
                    .replace("{database}", database.getDbName());
        }else if(database.getType().equals(DbTypeEnum.oracle.getCode())){
            ValidatorUtils.validateEntity(database, OracleGroup.class);
            if(database.getOracleType().equals(DbTypeEnum.oracleServerName.getCode())){
                return DB_URL_TEMPLATE.get(DbTypeEnum.oracleServerName.name())
                        .replace("{host}", database.getHost())
                        .replace("{port}", database.getPort())
                        .replace("{service_name}", database.getDbName());
            }else{
                return DB_URL_TEMPLATE.get(DbTypeEnum.oracleSid.name())
                        .replace("{host}", database.getHost())
                        .replace("{port}", database.getPort())
                        .replace("{sid}", database.getDbName());
            }
        }else if(database.getType().equals(DbTypeEnum.sqlServer.getCode())){
            ValidatorUtils.validateEntity(database, MysqlGroup.class);
            return DB_URL_TEMPLATE.get(DbTypeEnum.sqlServer.name())
                    .replace("{host}", database.getHost())
                    .replace("{port}", database.getPort())
                    .replace("{database}", database.getDbName());
        }else if(database.getType().equals(DbTypeEnum.dm.getCode())){
            ValidatorUtils.validateEntity(database, MysqlGroup.class);
            return DB_URL_TEMPLATE.get(DbTypeEnum.dm.name())
                    .replace("{host}", database.getHost())
                    .replace("{port}", database.getPort())
                    .replace("{database}", database.getDbName());
        }else if(database.getType().equals(DbTypeEnum.postgresql.getCode())){
            ValidatorUtils.validateEntity(database, MysqlGroup.class);
            return DB_URL_TEMPLATE.get(DbTypeEnum.postgresql.name())
                    .replace("{host}", database.getHost())
                    .replace("{port}", database.getPort())
                    .replace("{database}", database.getDbName());
        }else if(database.getType().equals(DbTypeEnum.oceanbase.getCode())){
            ValidatorUtils.validateEntity(database, MysqlGroup.class);
            return DB_URL_TEMPLATE.get(DbTypeEnum.oceanbase.name())
                    .replace("{host}", database.getHost())
                    .replace("{port}", database.getPort())
                    .replace("{database}", database.getDbName());
        }else if(database.getType().equals(DbTypeEnum.hive.getCode())){
            ValidatorUtils.validateEntity(database, MysqlGroup.class);
            return DB_URL_TEMPLATE.get(DbTypeEnum.hive.name())
                    .replace("{host}", database.getHost())
                    .replace("{port}", database.getPort())
                    .replace("{database}", database.getDbName());
        }
        return database.getUrl();
    }

    public static DriverManagerDataSource getDataSource(DatabaseDTO databaseDTO) throws Exception{
        try{
            DriverManagerDataSource dataSource = new DriverManagerDataSource();
            dataSource.setUsername(databaseDTO.getUsername());
            dataSource.setPassword(databaseDTO.getPassword());
            if(databaseDTO.getType().equals(DbTypeEnum.hive.getCode())){
                dataSource.setDriverClassName("org.apache.hive.jdbc.HiveDriver");
            }else{
                dataSource.setDriverClassName(DriverUtil.identifyDriver(databaseDTO.getUrl()));
            }
            dataSource.setUrl(databaseDTO.getUrl());
            DriverManager.setLoginTimeout(3);
            return dataSource;
        }catch (Exception ex){
            throw new DataAccessException(ex);
        }
    }

    public static List excutePage(DatabaseDTO databaseDTO, String sql, Page page) throws Exception{
        DriverManagerDataSource dataSource = getDataSource(databaseDTO);
        try{
            return Db.use(dataSource).page(sql.endsWith(";") ? sql.substring(0, sql.length()-1) : sql, page);
        }catch (Exception ex){
            throw new DataAccessException(ex);
        }
    }

    public static int excuteCUD(DatabaseDTO databaseDTO, String sql) throws Exception{
        DriverManagerDataSource dataSource = getDataSource(databaseDTO);
        try{
            return Db.use(dataSource).execute(sql.endsWith(";") ? sql.substring(0, sql.length()-1) : sql, null);
        }catch (Exception ex){
            throw new DataAccessException(ex);
        }
    }

    public static boolean testConn(DatabaseDTO databaseDTO) throws Exception{
        try{
            if(databaseDTO.getType().equals(DbTypeEnum.mongodb.getCode())){
                MongoClient mongoClient = null;
                try {
                    mongoClient = getMongoClient(databaseDTO);
                    MongoDatabase database = mongoClient.getDatabase(databaseDTO.getDbName());
                    MongoCollection<Document> doc = database.getCollection("test");
                    doc.insertOne(new Document("name","连接测试"));
                    return true;
                }finally {
                    if (mongoClient != null) {
                        mongoClient.close();
                    }
                }
            }else if(databaseDTO.getType().equals(DbTypeEnum.hbase.getCode())){
                org.apache.hadoop.hbase.client.Connection conn = getHbaseConn(databaseDTO);
                Admin admin = null;
                try{
                    admin = conn.getAdmin();
                    admin.listTables();
                }catch (Exception ex){
                    throw ex;
                }finally {
                    if(admin != null){
                        admin.close();
                    }
                    if(conn != null){
                        conn.close();
                    }
                }
                return true;
            }else{
                DriverManagerDataSource dataSource = getDataSource(databaseDTO);
                Connection connection = dataSource.getConnection();
                try {
                    return connection.isValid(3000);
                }finally {
                    connection.close();
                }
            }
        }catch (Exception ex){
            throw new DataAccessException(ex.getMessage());
        }
    }



    public static List<TableNamesDTO> getTableNames(DatabaseDTO databaseDTO) throws Exception{
        try{
            if(databaseDTO.getType().equals(DbTypeEnum.mongodb.getCode())){
                MongoClient client = null;
                List<TableNamesDTO> namesDTOS = new ArrayList<>();
                try{
                    client = getMongoClient(databaseDTO);
                    MongoIterable<String> names = client.getDatabase(databaseDTO.getDbName()).listCollectionNames();
                    for (String name : names) {
                        TableNamesDTO namesDTO = new TableNamesDTO();
                        namesDTO.setTableName(name);
                        namesDTOS.add(namesDTO);
                    }
                }finally {
                    if(client != null){
                        client.close();
                    }
                }
                return namesDTOS;
            }else if(databaseDTO.getType().equals(DbTypeEnum.hbase.getCode())){
                List<TableNamesDTO> tableNames = new ArrayList<>();
                org.apache.hadoop.hbase.client.Connection conn = getHbaseConn(databaseDTO);
                Admin admin = null;
                try{
                    admin = conn.getAdmin();
                    HTableDescriptor[] tables = admin.listTables();
                    for (HTableDescriptor table : tables) {
                        TableNamesDTO namesDTO = new TableNamesDTO();
                        namesDTO.setTableName(table.getNameAsString());
                        tableNames.add(namesDTO);
                    }
                    return tableNames;
                }catch (Exception ex){
                    throw ex;
                }finally {
                    if(admin != null){
                        admin.close();
                    }
                    if(conn != null){
                        conn.close();
                    }
                }
            }else{
                DataSource dataSource = getDataSource(databaseDTO);
                Db db = Db.use(dataSource);
                if(databaseDTO.getType().equals(DbTypeEnum.mysql.getCode())){
                    return db.query(DB_TABLE_NAME.get(DbTypeEnum.mysql.name()), TableNamesDTO.class);
                }else if(databaseDTO.getType().equals(DbTypeEnum.oracle.getCode())){
                    return db.query(DB_TABLE_NAME.get(DbTypeEnum.oracle.name()), TableNamesDTO.class);
                }else if(databaseDTO.getType().equals(DbTypeEnum.sqlServer.getCode())){
                    return db.query(DB_TABLE_NAME.get(DbTypeEnum.sqlServer.name()), TableNamesDTO.class);
                }else if(databaseDTO.getType().equals(DbTypeEnum.dm.getCode())){
                    return db.query(DB_TABLE_NAME.get(DbTypeEnum.dm.name()), TableNamesDTO.class);
                }else if(databaseDTO.getType().equals(DbTypeEnum.postgresql.getCode())){
                    String sql = DB_TABLE_NAME.get(DbTypeEnum.postgresql.name());
                    if(StrUtil.isNotBlank(databaseDTO.getTableSchema())){
                        sql += " where schemaname = '"+databaseDTO.getTableSchema()+"'";
                    }
                    return db.query(sql, TableNamesDTO.class);
                }else if(databaseDTO.getType().equals(DbTypeEnum.oceanbase.getCode())){
                    return db.query(DB_TABLE_NAME.get(DbTypeEnum.oceanbase.name()), TableNamesDTO.class);
                }else if(databaseDTO.getType().equals(DbTypeEnum.hive.getCode())){
                    List<TableNamesDTO> tableNames = new ArrayList<>();
                    List<Entity> objects = db.query(DB_TABLE_NAME.get(DbTypeEnum.hive.name()), Entity.class);
                    for(Entity entity : objects){
                        TableNamesDTO tableName = new TableNamesDTO();
                        tableName.setTableName(entity.getStr("tab_name"));
                        tableNames.add(tableName);
                    }
                    return tableNames;
                }
            }
            throw new DataAccessException("数据库暂时不支持，敬请期待哦!!!");
        }catch (Exception ex){
            throw new DataAccessException("数据源【"+databaseDTO.getName()+"】异常：" + ex.getMessage(), ex);
        }
    }

    public static List<Map> getFieldNamesByTable(DatabaseDTO databaseDTO, String table) throws Exception{
        try{
            DataSource dataSource = getDataSource(databaseDTO);
            Db db = Db.use(dataSource);
            if(databaseDTO.getType().equals(DbTypeEnum.mysql.getCode())){
                return db.query(DB_TABLE_FIELD_NAME.get(DbTypeEnum.mysql.name()).replace("{tableName}", table), Map.class);
            }else if(databaseDTO.getType().equals(DbTypeEnum.oracle.getCode())){
                return db.query(DB_TABLE_FIELD_NAME.get(DbTypeEnum.oracle.name()).replace("{tableName}", table), Map.class);
            }else if(databaseDTO.getType().equals(DbTypeEnum.sqlServer.getCode())){
                return db.query(DB_TABLE_FIELD_NAME.get(DbTypeEnum.sqlServer.name()).replace("{tableName}", table), Map.class);
            }else if(databaseDTO.getType().equals(DbTypeEnum.dm.getCode())){
                return db.query(DB_TABLE_FIELD_NAME.get(DbTypeEnum.dm.name()).replace("{tableName}", table), Map.class);
            }else if(databaseDTO.getType().equals(DbTypeEnum.postgresql.getCode())){
                return db.query(DB_TABLE_FIELD_NAME.get(DbTypeEnum.postgresql.name()).replace("{tableName}", table), Map.class);
            }else if(databaseDTO.getType().equals(DbTypeEnum.oceanbase.getCode())){
                return db.query(DB_TABLE_FIELD_NAME.get(DbTypeEnum.oceanbase.name()).replace("{tableName}", table), Map.class);
            }else if(databaseDTO.getType().equals(DbTypeEnum.hive.getCode())){
                List<Map> fieldNames = new ArrayList<>();
                List<Entity> entities = db.query(DB_TABLE_FIELD_NAME.get(DbTypeEnum.hive.name()).replace("{tableName}", table));
                for (Entity entity : entities){
                    String columnName = entity.getStr("col_name");
                    String dataType = entity.getStr("data_type");
                    String comment = entity.getStr("comment");

                    JSONObject object = new JSONObject();
                    object.put("columnName", columnName);
                    object.put("dataType", dataType);
                    object.put("comment", comment);

                    fieldNames.add(object);
                }
                return fieldNames;
            }
            throw new DataAccessException("数据库暂时不支持，敬请期待哦!!!");
        }catch (Exception ex){
            throw new DataAccessException("数据源【"+databaseDTO.getName()+"】异常：" + ex.getMessage(), ex);
        }
    }

    public static List<Map> getFieldNamesBySql(DatabaseDTO databaseDTO, String querySql) throws Exception{
        try{
            DataSource dataSource = getDataSource(databaseDTO);
            Db db = Db.use(dataSource);
            Connection connection = db.getConnection();

            List<Map> res = Lists.newArrayList();
            Statement stmt = null;
            ResultSet rs = null;
            try {
                querySql = querySql.replace(";", "");

                //拼装sql语句，在后面加上 where 1=0 即可,此查询只查询列名，不要去查真正的数据
                querySql = "select * from ("+querySql+") a where 1=0";

                //获取所有字段
                stmt = connection.createStatement();
                rs = stmt.executeQuery(querySql);
                ResultSetMetaData metaData = rs.getMetaData();

                int columnCount = metaData.getColumnCount();
                for (int i = 1; i <= columnCount; i++) {
                    Map item = new HashMap(6);
                    item.put("name", metaData.getColumnName(i).replace("a.", ""));
                    item.put("type", metaData.getColumnTypeName(i));
                    res.add(item);
                }
            } finally {
                JdbcUtils.closeConnection(connection);
                JdbcUtils.closeResultSet(rs);
                JdbcUtils.closeStatement(stmt);
            }

            return res;
        }catch (Exception ex){
            throw new DataAccessException("数据源【"+databaseDTO.getName()+"】异常：" + ex.getMessage(), ex);
        }
    }

    private static org.apache.hadoop.hbase.client.Connection getHbaseConn(DatabaseDTO databaseDTO) throws Exception{
        List<String> zkList = StrUtil.split(databaseDTO.getUrl(), ",");
        List<String> zkHostList = zkList.stream().map(s -> s.split(":")[0]).collect(Collectors.toList());

        Configuration conf = HBaseConfiguration.create();
        conf.set("hbase.zookeeper.quorum", StrUtil.join(",", zkHostList));
        conf.set("hbase.zookeeper.property.clientPort", zkList.get(0).split(":")[1]);
        conf.setInt("zookeeper.recovery.retry.maxsleeptime", 2000);
        conf.setInt("zookeeper.session.timeout", 2000);
        conf.setInt("zookeeper.recovery.retry", 1);
        conf.setInt("hbase.client.pause", 2000);
        conf.setInt("hbase.client.retries.number", 1);
        org.apache.hadoop.hbase.client.Connection connection = ConnectionFactory.createConnection(conf);
        return connection;
    }
    private static MongoClient getMongoClient(DatabaseDTO databaseDTO){
        MongoClient mongoClient = null;

        try{
            MongoClientOptions.Builder builder = new MongoClientOptions.Builder()
                    .socketTimeout(5000)
                    .connectTimeout(5000)
                    .serverSelectionTimeout(6000)
                    .maxWaitTime(5000);
            if(databaseDTO.getUrl().startsWith(MONGODB_URL_STARTWITH)){
                MongoClientURI uri = new MongoClientURI(databaseDTO.getUrl(), builder);
                mongoClient = new MongoClient(uri);
            }else{
                /**
                 * 默认认证机制
                 */
                List<ServerAddress> seedList = new ArrayList<>();
                String[] hosts = databaseDTO.getUrl().split(",");
                for (String host : hosts) {
                    ServerAddress serverAddress = new ServerAddress(host.split(":")[0], Integer.parseInt(host.split(":")[1]));
                    seedList.add(serverAddress);
                }
                MongoCredential credential = MongoCredential.createCredential(databaseDTO.getUsername(), databaseDTO.getDbName(),
                        databaseDTO.getPassword().toCharArray());

                mongoClient = new MongoClient(seedList, Arrays.asList(credential), builder.build());
            }
            return mongoClient;
        }catch (Exception ex){
            if(mongoClient != null){
                mongoClient.close();
            }
        }
        return null;
    }
}
